package ai.plantdata.dao.strategy.impl;

import ai.plantdata.dao.dto.UnrelatedEntitySeparateTab;
import ai.plantdata.dao.strategy.SeparateHandle;
import ai.plantdata.dao.util.JdbcUtils;
import ai.plantdata.graph.api.Node;
import ai.plantdata.graph.api.Property;
import ai.plantdata.graph.api.schema.ConceptDefinition;
import ai.plantdata.graph.api.schema.NumericDefinition;
import ai.plantdata.graph.mongo.MongoGraphStore;
import ai.plantdata.vo.DataSourceConfig;
import ai.plantdata.dao.util.BeanTransform;
import ai.plantdata.vo.SeparateTable;
import org.springframework.util.CollectionUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Author: WangHui
 * @Date: 2021/7/16 18:28
 * @Description:
 */
public class NoAssociationEntity implements SeparateHandle {
    @Override
    public List<ConceptDefinition> schemaHandle(SeparateTable separateDTO, DataSourceConfig dataSourceConfig, MongoGraphStore store) {
        UnrelatedEntitySeparateTab entityTable = BeanTransform.separateTableToUnrelatedEntitySeparateTab(separateDTO);
        String conceptName = entityTable.getConceptName();
        String conceptMeanTag = entityTable.getConceptMeanTag();
        ConceptDefinition parentConcept = ConceptDefinition.create(conceptName, conceptMeanTag);
        Connection conn = JdbcUtils.getConnection(dataSourceConfig);
        String tableName = entityTable.getTableName();
        List<String> fieldNames = entityTable.getFieldName();
        List<NumericDefinition> numDef = getNumDef(conn, tableName, fieldNames);
        parentConcept.setAttributes(numDef);
        store.saveSchema(parentConcept);
        return Collections.singletonList(parentConcept);
    }

    @Override
    public void entityHandle(SeparateTable separateDTO, DataSourceConfig dataSourceConfig, MongoGraphStore store) {
        try {
            UnrelatedEntitySeparateTab entityTable = BeanTransform.separateTableToUnrelatedEntitySeparateTab(separateDTO);
            String conceptName = entityTable.getConceptName();
            String conceptMeanTag = entityTable.getConceptMeanTag();
            Connection conn = JdbcUtils.getConnection(dataSourceConfig);
            List<String> fieldName = entityTable.getFieldName();
            if (CollectionUtils.isEmpty(fieldName)) {
                fieldName = new ArrayList<>();
            }
            StringBuilder str = new StringBuilder();
            for (String s : fieldName) {
                str.append(" , ").append(s);

            }
            String meanTagField = entityTable.getMeanTagField();
            String nameField = entityTable.getNameField();
            String tableName = entityTable.getTableName();
            List<Node> nodes = new ArrayList<>();
            String sql;
            if (meanTagField == null) {
                sql = "select %s  %s from %s";
                sql = String.format(sql, nameField, str, tableName);
                PreparedStatement ps = conn.prepareStatement(sql);
                ResultSet rs = ps.executeQuery();
                while (rs.next()) {
                    Node node = Node.create(rs.getObject(1, String.class)).label(conceptName);
                    List<Property> properties = new ArrayList<>();
                    for (int i = 0; i < fieldName.size(); i++) {
                        Property property = Property.create(fieldName.get(i), rs.getObject(2 + i));
                        properties.add(property);
                    }
                    node.setProperties(properties);
                    nodes.add(node);
                    if (nodes.size() % 10_000 == 0) {
                        //保存关系
                        store.saveNodeWithProperty(nodes);
                        nodes.clear();
                    }
                }
                JdbcUtils.close(ps, rs);
            } else {
                sql = "select %s ,%s, %s %s from %s";
                sql = String.format(sql, nameField, meanTagField, str, tableName);
                PreparedStatement ps = conn.prepareStatement(sql);
                ResultSet rs = ps.executeQuery();
                while (rs.next()) {
                    Node node = Node.create(rs.getObject(1, String.class), rs.getObject(2, String.class)).label(conceptName, conceptMeanTag);
                    List<Property> properties = new ArrayList<>();
                    for (int i = 0; i < fieldName.size(); i++) {
                        Property property = Property.create(fieldName.get(i), rs.getObject(3 + i));
                        properties.add(property);
                    }
                    node.setProperties(properties);
                    nodes.add(node);
                    if (nodes.size() % 10_000 == 0) {
                        //保存关系
                        store.saveNodeWithProperty(nodes);
                        nodes.clear();
                    }
                }
                JdbcUtils.close(ps, rs);
                conn.close();
            }
            if (!nodes.isEmpty()) {
                store.saveNodeWithProperty(nodes);
                nodes.clear();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
